package com.ktgj.common.core.utils.helper;

import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;

import com.ktgj.common.core.utils.xml.XmlHelp;
import org.apache.logging.log4j.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

public class FileHelper
{
	private final static Logger LOGGER = LoggerFactory.getLogger(XmlHelp.class);
	static final Charset DEF_CHAR_SET = Charset.forName("utf-8");

	public static String readAllText(String filename)
	{
		return readAllText(filename, DEF_CHAR_SET);
	}

	public static String readAllText(String filename, Charset charset)
	{
		byte[] buffer = readAllBytes(filename);
		if (buffer.length == 0) return "";

		return new String(buffer, charset);
	}

	public static void createDir(String dir)
	{
		File file = new File(dir);
		if (file.exists()) return;
		file.mkdirs();
	}

	public static void deleteIfExists(String fileName)
	{
		File file = new File(fileName);
		if (!file.exists()) return;
		file.delete();
	}

	public static void copy(String from, String to)
	{
		File file = new File(from);
		if (!file.exists()) return;
		deleteIfExists(to);
		save(to, readAllBytes(from));
	}

	public static boolean exists(String filename)
	{
		File file = new File(filename);
		return file.exists();
	}

	public static byte[] readAllBytes(String filename)
	{
		File file = new File(filename);
		if (!file.exists())
		{
			return new byte[0];
		}

		FileInputStream stream = null;
		try
		{
			int length = (int) file.length();
			byte[] buffer = new byte[length];

			int left = length;

			stream = new FileInputStream(file);
			while (left > 0)
			{
				left -= stream.read(buffer, length - left, left > 1024 ? 1024 : left);
			}

			return buffer;
		}
		catch (Exception e)
		{
			LOGGER.error(e.getMessage());
			return new byte[0];
		}
		finally
		{
			if (stream != null)
			{
				try
				{
					stream.close();
				}
				catch (Exception e)
				{
					LOGGER.error(e.getMessage());
				}
			}
		}
	}

	public static byte[] readAllBytes(int length, InputStream stream)
	{
		try
		{
			byte[] buffer = new byte[length];
			int left = length;
			while (left > 0)
			{
				left -= stream.read(buffer, length - left, left > 1024 ? 1024 : left);
			}

			return buffer;
		}
		catch (Exception e)
		{
			LOGGER.error(e.getMessage());
			return new byte[0];
		}
		finally
		{
			if (stream != null)
			{
				try
				{
					stream.close();
				}
				catch (Exception e)
				{
					LOGGER.error(e.getMessage());
				}
			}
		}
	}

	public static boolean save(String path, byte[] buffer)
	{
		File file = new File(path);
		FileOutputStream stream = null;
		try
		{
			stream = new FileOutputStream(file);
			stream.write(buffer);
			stream.flush();
			return true;
		}
		catch (Exception e)
		{
			LOGGER.error(e.getMessage());
			return false;
		}

		finally
		{
			if (stream != null)
			{
				try
				{
					stream.close();
				}
				catch (IOException e)
				{
					LOGGER.error(e.getMessage());
				}
			}
		}
	}

	public static boolean save(String path, byte[] buffer, Charset charset)
	{
		File file = new File(path);
		FileOutputStream stream = null;
		try
		{
			stream = new FileOutputStream(file);
			OutputStreamWriter writer = new OutputStreamWriter(stream, charset);
			char[] buf = new char[buffer.length];
			for (int i = 0; i < buffer.length; i++)
			{
				buf[i] = (char) buffer[i];
			}

			writer.write(buf);
			writer.flush();
			return true;
		}
		catch (Exception e)
		{
			LOGGER.error(e.getMessage());
			return false;
		}

		finally
		{
			if (stream != null)
			{
				try
				{
					stream.close();
				}
				catch (IOException e)
				{
					LOGGER.error(e.getMessage());
				}
			}
		}

	}
	
	public static boolean deleteFolder(File file)
	{
		if (!file.exists())
		{
			return false;
		}
		if (file.isDirectory())
		{
			File[] files = file.listFiles();
			for (File f : files)
			{
				deleteFolder(f);
			}
		}
		return file.delete();
	}
	
	public static boolean copy(InputStream stream,String to) throws IOException
	{
		return copy(stream,Paths.get(to));
	}
	
	static boolean copy(InputStream stream,Path to) throws IOException
	{
		  Files.copy(stream,to, StandardCopyOption.REPLACE_EXISTING);
		  return to.toFile().exists();
	}
	
	public static boolean copy(MultipartFile file,String targetPath,String newName) throws IOException
	{
		if(StringHelper.isNullOrEmpty(newName))
		{
			newName = file.getOriginalFilename();
		}
		Path path1 = Paths.get(targetPath,newName);
		return copy(file.getInputStream(),path1);
	}
	
	public static <T> void objectXmlEncoder(T obj, String fileName) throws FileNotFoundException, IOException, Exception
	{
		File fo = new File(fileName);
		if (!fo.exists())
		{
			String path = fileName.substring(0, fileName.lastIndexOf("."));
			File pFile = new File(path);
			pFile.mkdirs();
		}
		FileOutputStream fos = new FileOutputStream(fo);
		XMLEncoder encoder = new XMLEncoder(fos);
		encoder.writeObject(obj);
		encoder.flush();
		encoder.close();
	}
	
	@SuppressWarnings("unchecked")
	public static List<Object> objectXmlDecoder(String objSource) throws FileNotFoundException, IOException, Exception
	{
		List<Object> lstData = new ArrayList<Object>();
		File fin = new File(objSource);
		FileInputStream fins = new FileInputStream(fin);
		XMLDecoder decoder = new XMLDecoder(fins);
		try
		{
			lstData=(List<Object>)decoder.readObject();
		} catch (Exception e)
		{
			// TODO: handle exception
		}
		fins.close();
		decoder.close();
		return lstData;
	}
}
